package controller

import (
	"bytes"
	"github.com/dchest/captcha"
	"github.com/gin-gonic/gin"
	"net/http"
	"path"
	"shop-common/library/serializer"
	"time"
)

type CaptchaController struct {
}

// @Tags 其它
// @Summary 生成验证码ID
// @function: Generate
// @Accept  json
// @Produce  json
// @Success 200 {string} string "{"code": 0,"result":{},"message":"验证码获取成功", time: 1618408366}"
// @Router /captcha [get]
func (c *CaptchaController) Generate(ctx *gin.Context) {
	// 设置验证码的数字长度（个数）
	captchaId := captcha.NewLen(4)
	serializer.SuccessData(ctx, "验证码获取成功", map[string]interface{}{
		"id":      captchaId,
		"src":     "/captcha/" + captchaId + ".png",
		"refresh": "?reload=1",
	})
}

// @Tags 其它
// @Summary 获取验证码图像
// @function: GetCaptcha
// @Accept  json
// @Produce  json
// @Param id path int true "captchaId"
// @Success 200 {string} string "{"code": 0,"result":{},"message":"生成验证码成功", time: 1618408366}"
// @Router /captcha/{captchaId} [get]
func (c *CaptchaController) GetCaptcha(ctx *gin.Context) {
	captchaId := ctx.Param("captchaId")
	_, file := path.Split(ctx.Request.URL.Path)
	ext := path.Ext(file)
	id := file[:len(file)-len(ext)]
	if ext == "" || captchaId == "" {
		serializer.Echo(ctx, 400350, "获取验证码：提交的验证码参数无效,请检查验证码ID以及文件名后缀是否完整", nil)
		return
	}

	if ctx.Query("reload") != "" {
		captcha.Reload(id)
	}

	ctx.Header("Cache-Control", "no-cache, no-store, must-revalidate")
	ctx.Header("Pragma", "no-cache")
	ctx.Header("Expires", "0")

	var vBytes bytes.Buffer
	if ext == ".png" {
		ctx.Header("Content-Type", "image/png")
		// 设置实际业务需要的验证码图片尺寸（宽 X 高），captcha.StdWidth, captcha.StdHeight 为默认值，请自行修改为具体数字即可
		_ = captcha.WriteImage(&vBytes, id, captcha.StdWidth, captcha.StdHeight)
		http.ServeContent(ctx.Writer, ctx.Request, id+ext, time.Time{}, bytes.NewReader(vBytes.Bytes()))
	}
}

func VerifyCaptchaCode() func(ctx *gin.Context) {
	return func(ctx *gin.Context) {
		captchaId := ctx.Param("captchaId")
		value := ctx.Param("code")
		if captchaId == "" || value == "" {
			serializer.Echo(ctx, 400351, "校验验证码：提交的参数无效，请确保提交的验证码ID和值有效", nil)
			ctx.Abort()
			return
		}
		if !captcha.VerifyString(captchaId, value) {
			serializer.Echo(ctx, 400355, "验证码校验失败", nil)
			ctx.Abort()
			return
		}
		ctx.Next()
	}
}
